﻿using DeHeng_Mes.Constant;
using DeHeng_Mes.Dao;
using DeHeng_Mes.Dao.PlcDao;
using DeHeng_Mes.Model;
using DeHeng_Mes.Model.Boss;
using DeHeng_Mes.Model.BossModel;
using DeHeng_Mes.Model.ConfigModel;
using DeHeng_Mes.Model.PlcModel;
using DeHeng_Mes.Model.Table;
using DeHeng_Mes.Service.Plc;
using DeHeng_Mes.Thread;
using DeHeng_Mes.Utils;
using FluentFTP;
using NPOI.SS.Formula.Functions;
using S7.Net;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using yingli_ningbo.Helpers;
using static DeHeng_Mes.Utils.Tools;
using MappingTable = DeHeng_Mes.Utils.MappingTable;
using RichTextBox = System.Windows.Forms.RichTextBox;
using SqlSugar;
using Org.BouncyCastle.Tls;
using System.Windows.Input;
using System.IO;
using DeHeng_Mes.Service;
using System.Management.Instrumentation;
using DeHeng_Mes.Model.Singleton;
using DeHeng_Mes.Model.ViewModel;
using DeHeng_Mes.Model.OrderSingleton;

namespace DeHeng_Mes.Business
{
    public partial class MainForm : Form
    {

        #region 全局成员
        private PlcConnectionManager _plcConnectionManager;
        private FactoryMes factoryMesThread;
        private PlcCollectionData plcCollectionData = new PlcCollectionData();
        List<PlcOrderConfigModel> readPlcList = PlcOrderConfigModelList.ReadPlcList;
        PlcServicees PlcService = new PlcServicees();
        ErrorGather errorGather = new ErrorGather();
        RealTimeThread realTime = new RealTimeThread();
        PowerGather powerGather = new PowerGather();
        MesDataPush dataPush = new MesDataPush();
        #endregion

        public MainForm()
        {
            InitializeComponent();

            FormClosing += new FormClosingEventHandler(MainForm_FormClosing);
        }

        /// <summary>
        /// 私有转换公有
        /// </summary>
        public RichTextBox ProductionLogsText
        {
            get => ProductionLogs;

            set => ProductionLogs = value;
        }

        /// <summary>
        /// 私有转换公有
        /// </summary>
        public RichTextBox DeviceLogsText
        {
            get => DeviceLogs;

            set => DeviceLogs = value;
        }

        /// <summary>
        /// 窗体关闭事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 在这里执行需要的任务
            DialogResult result = MessageBox.Show("确定要关闭吗？", "确认", MessageBoxButtons.YesNo);

            // 如果用户点击了 No，则取消关闭
            if (result == DialogResult.No)
            {
                e.Cancel = true;
            }
            else
            {
                // 读取当日最终耗电量与产量
                PlcService.GetPowerAndProdution(false);
            }
        }

        /// <summary>
        /// 窗体首次加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryInfo_LoadAsync(object sender, EventArgs e)
        {
            factoryMesThread = new FactoryMes();

            ToolControl(this);

            List<PlcConfigModel> plcList = InitPlcConfig();

            if (plcList != null && plcList.Count > 0)
            {
                _plcConnectionManager = new PlcConnectionManager(plcList);
            }
            if (readPlcList != null)
            {
                ProduceLogText("初始化订单模型缓存成功");
            }

            // plc连接线程
            _plcConnectionManager.ConnectToPlc();

            // 配置Plc模型
            _ = factoryMesThread.OrderIsOk();

            // 启动Plc交互采集线程
            _ = plcCollectionData.CollectionTask();

            // 启动故障采集线程
            _ = errorGather.PlcErrorGather();

            // 启动故障结束时间采集线程
            _ = errorGather.PlcErrorGatherEndTime();

            // 启动小时能耗采集
            //_ = powerGather.GetHourPower();

            // 启动小时产量采集线程
            //_ = realTime.HourProduction();

            // 启动0点监控线程
            //_ = PlcService.Timer();

            // 启动来料管控接口
            //_ = PlcService.PartResult();

            // 启动工厂数据推送线程
            _ = dataPush.pushTask();

            // 启动CSV数据采集线程
            Task.Run(async () => { await PlcService.ReadCSVData(); });

            // 启动工厂Mes线程监听订单信息
            _ = factoryMesThread.GetOrderDetails();
        }

        #region 自定义方法

        /// <summary>
        /// 初始化PLC配置
        /// </summary>
        private List<PlcConfigModel> InitPlcConfig()
        {
            string[] ips = new string[] { "192.168.12.1", "192.168.13.1", "192.168.12.160", "192.168.12.165" };
            string[] names = new string[] { "DOOR-01", "DOOR-02", "DOOR-03", "DOOR-04" };
            string[] nicks = new string[] { "W03-门槛线自动线前段", "W03-门槛线自动线后段", "W03-门槛左侧压铆工作站", "W03-门槛右侧压铆工作站" };
            List<PlcConfigModel> plcConfigs = new List<PlcConfigModel>();
            for (int i = 0; i < ips.Length; i++)
            {
                PlcConfigModel plcConfigModel = new PlcConfigModel();
                plcConfigModel.plc = new Plc(CpuType.S71500, ips[i], 0, 1);
                plcConfigModel.nick = nicks[i];
                plcConfigModel.name = names[i];
                plcConfigModel.cpu = CpuType.S71500;
                plcConfigModel.ip = ips[i];
                plcConfigModel.rack = 0;
                plcConfigModel.slot = 1;
                plcConfigModel.heartBeat = 5000;
                plcConfigModel.retryInterval = 3000;
                plcConfigModel.readInterval = 10000;
                plcConfigModel.isConnected = false;
                plcConfigs.Add(plcConfigModel);
            }
            return plcConfigs;
        }

        #endregion

        private void button1_Click(object sender, EventArgs e)
        {
            /*string orderId = $"NBXS-{DateTime.Now}";

            decimal produceNum = 500;

            string carType = "W03-DOOR";

            // 遍历所有 PLC 配置并找到符合条件的 PLC 实例
            foreach (var plcConfig in PlcConnectionManager.plcContainer)
            {
                if (plcConfig.isConnected)
                {
                    // 读取PLC中订单号的存储位置
                    byte[] bytes = plcConfig.plc.ReadBytes(DataType.DataBlock, SystemConstant.ORDER_DB, SystemConstant.ORDER_ID_OFF, 256);
                    string isSaveOrderId = PlcDao.ParseS7String(bytes);
                    // 如果订单号为空，则写入订单信息
                    if (string.IsNullOrEmpty(isSaveOrderId))
                    {
                        plcConfig.plc.WriteBytes(DataType.DataBlock, SystemConstant.ORDER_DB, SystemConstant.ORDER_ID_OFF, Tools.ConvertToPlcString(orderId, orderId.Length));
                        plcConfig.plc.WriteBytes(DataType.DataBlock, SystemConstant.ORDER_DB, SystemConstant.ORDER_CARTEPY_OFF, Tools.ConvertToPlcString(carType, carType.Length));
                        plcConfig.plc.Write(DataType.DataBlock, SystemConstant.ORDER_DB, SystemConstant.ORDER_PRODUCENUM_OFF, short.Parse((Convert.ToInt16(produceNum)).ToString()));
                        Tools.ProduceLogText($"订单已成功下发到PLC：{plcConfig.name}");

                        // 配置模型
                        readPlcList.Add(new PlcOrderConfigModel()
                        {
                            plc = plcConfig.plc,
                            PlcName = plcConfig.name,
                            Status = false,
                            OrderId = orderId,
                            ProduceNum = produceNum,
                            CarType = carType,
                            StartTime = DateTime.Now.ToString()
                        });
                        Tools.ProduceLogText($"工单下发至{plcConfig.name}成功，工单号为{orderId}，数量为{produceNum}，车型为{carType}，当前工单缓存池中包含{readPlcList.Count}个工单");

                    }
                    else
                    {
                        Tools.ProduceLogTextError($"工单下发失败：{plcConfig.name}的Plc实例已经存在订单缓存，请先结束工单。");
                    }
                }
                else
                {
                    Tools.ProduceLogTextError($"工单下发失败：未找到{plcConfig.name}的Plc实例，请检查连接状态。");
                }
            }

            *//*// 读取当日最终耗电量与产量
            PlcService.GetPowerAndProdution(true);*/

            /* DateTime today = DateTime.Today;

             DateTime firstDayOfMonth = new DateTime(today.Year, today.Month, 1);

             DateTime lastDayOfMonth = new DateTime(today.Year, today.Month, DateTime.DaysInMonth(today.Year, today.Month));

             Tools.ProduceLogText($"{firstDayOfMonth}-{lastDayOfMonth}");*/


            try
            {
                using (var db = ViewSugarConfig.Db)
                {
                    List<LineMesDataDtl> lineMesDataDtls = db.Queryable<LineMesDataDtl>().Where(x => x.DataId == "a6d725f1697556dbeb81fc6106a2f28889bfb5ba0f3c84284f51b11447c511fb").ToList();

                    foreach (var item in lineMesDataDtls)
                    {
                        Tools.ProduceLogText($"测试：{item.CreateTime}.{item.Count}.{item.TraceId}");
                    }
                    
                }
            }
            catch (Exception ex)
            {
                Tools.ProduceLogTextError($"测试：{ex.Message}");
            }
        }
    }
}
